#include <stdlib.h>
#include <time.h>
#include "rtsp_resolver.h"
#include "rtsp_response.h"
#include "rtsp_unit.h"
#include "rtp_unit.h"
#include "Debug.h"

//响应选项
int rtsp_response_options(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    char buf[32];
    PBufStr_reset(&unit->str);                                                                          //重置字符串缓冲区
    PBufStr_str_add(&unit->str, "RTSP/1.0 200 OK\r\n");
    PBufStr_str_add(&unit->str, "CSeq: ");
    sprintf(buf, "%d\r\n", unit->info.CSeq);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "Public: OPTIONS,DESCRIBE,SETUP,PLAY,PAUSE,TEARDOWN\r\n");
    PBufStr_str_add(&unit->str, "\r\n");
    return ret;
}

//生成SDP
int rtsp_generate_sdp(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    PBufStr_reset(&unit->tmp_str);
    PBufStr_str_add(&unit->tmp_str, "v=0\r\n");
    PBufStr_str_add(&unit->tmp_str, "o=- 3520307046 3520307046 IN IP4 0.0.0.0\r\n");
    PBufStr_str_add(&unit->tmp_str, "c=IN IP4 0.0.0.0\r\n");
    PBufStr_str_add(&unit->tmp_str, "s=RTSP Session\r\n");
    PBufStr_str_add(&unit->tmp_str, "t=0 0\r\n");
    PBufStr_str_add(&unit->tmp_str, "m=video 0 RTP/AVP 96\r\n");
    PBufStr_str_add(&unit->tmp_str, "a=rtpmap:96 H264\r\n");
    PBufStr_str_add(&unit->tmp_str, "a=framerate:25\r\n");
    PBufStr_str_add(&unit->tmp_str, "\r\n");
    return ret;
}

//响应描述
int rtsp_response_describe(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    char buf[32];
    rtsp_generate_sdp(unit);//生成SDP描述

    PBufStr_reset(&unit->str);
    PBufStr_str_add(&unit->str, "RTSP/1.0 200 OK\r\n");
    PBufStr_str_add(&unit->str, "CSeq: ");
    sprintf(buf, "%d\r\n", unit->info.CSeq);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "Server: sunshine/1.11\r\n");
    PBufStr_str_add(&unit->str, "Date: Fri, 22 Jul 2011 07:06:14 GMT\r\n");
    PBufStr_str_add(&unit->str, "Content-Type: application/sdp\r\n");
    PBufStr_str_add(&unit->str, "Content-Base: %s\r\n");
    PBufStr_str_add(&unit->str, "Content-Length: ");
    sprintf(buf, "%d\r\n", unit->tmp_str.str_len);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "\r\n");
    PBufStr_str_add(&unit->str, unit->tmp_str.buf);

    return ret;
}

//响应设置
int rtsp_response_setup(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    char buf[32];
    if (unit->info.transport_protocol == RTSPINFO_TRANSPORT_TYPE_TCP) {
        ret = rtsp_response_Unsupported_Transport(unit);
        return ret;
    }

    PBufStr_reset(&unit->str);
    PBufStr_str_add(&unit->str, "RTSP/1.0 200 OK\r\n");
    PBufStr_str_add(&unit->str, "CSeq: ");
    sprintf(buf, "%d\r\n", unit->info.CSeq);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "Server: sunshine/1.11\r\n");
    PBufStr_str_add(&unit->str, "Date: Fri, 22 Jul 2011 07:06:14 GMT\r\n");
    PBufStr_str_add(&unit->str, "Session: ");

    //随机生成会话号
    if (unit->info.session == 0) {
        srand((unsigned) time(NULL));
        unit->info.session = rand();
    }
    sprintf(buf, "%u\r\n", unit->info.session);
    PBufStr_str_add(&unit->str, buf);

    PBufStr_str_add(&unit->str, "Transport: ");

    if (unit->info.transport_protocol == RTSPINFO_TRANSPORT_TYPE_TCP) {
//        //TCP响应
//        PBufStr_str_add(&unit->str, "RTP/AVP/TCP;");
//        PBufStr_str_add(&unit->str, "unicast;");
//        PBufStr_str_add(&unit->str, "interleaved=0-1;");
//        PBufStr_str_add(&unit->str, "destination=127.0.0.1;");
//        PBufStr_str_add(&unit->str, "source=127.0.0.1;");
//        PBufStr_str_add(&unit->str, "interleaved=0-1;");
//        PBufStr_str_add(&unit->str, "\r\n");
//        PBufStr_str_add(&unit->str, "\r\n");
    } else if (unit->info.transport_protocol == RTSPINFO_TRANSPORT_TYPE_UDP) {
        //UDP响应
        PBufStr_str_add(&unit->str, "RTP/AVP;");
        if (unit->info.transport_way == RTSPINFO_TRANSPORT_WAY_UNICAST) {
            PBufStr_str_add(&unit->str, "unicast;");
        } else if (unit->info.transport_way == RTSPINFO_TRANSPORT_WAY_MULTICAST) {
            PBufStr_str_add(&unit->str, "multicast;");
        }
        PBufStr_str_add(&unit->str, "client_port=");
        sprintf(buf, "%d", unit->info.crtp_port);
        PBufStr_str_add(&unit->str, buf);
        sprintf(buf, "-%d;", unit->info.crtcp_port);
        PBufStr_str_add(&unit->str, buf);

        PBufStr_str_add(&unit->str, "destination=127.0.0.1;");
        PBufStr_str_add(&unit->str, "source=127.0.0.1;");
        PBufStr_str_add(&unit->str, "server_port=");

        //申请端口号
        unit->info.srtp_port = RTSPService_PortMap_malloc(unit->service);   //获取RTP发送端口
        unit->info.srtcp_port = unit->info.srtp_port + 1;                   //获取RTCP发送端口

        sprintf(buf, "%d", unit->info.srtp_port);
        PBufStr_str_add(&unit->str, buf);
        sprintf(buf, "-%d", unit->info.srtcp_port);
        PBufStr_str_add(&unit->str, buf);
        PBufStr_str_add(&unit->str, "\r\n");
        PBufStr_str_add(&unit->str, "\r\n");
    }
    return ret;
}

//响应播放
int rtsp_response_play(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    char buf[32];
    PBufStr_reset(&unit->str);
    PBufStr_str_add(&unit->str, "RTSP/1.0 200 OK\r\n");
    PBufStr_str_add(&unit->str, "CSeq: ");
    sprintf(buf, "%d\r\n", unit->info.CSeq);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "Server: sunshine/1.11\r\n");
    PBufStr_str_add(&unit->str, "Date: Fri, 22 Jul 2011 07:06:14 GMT\r\n");
    PBufStr_str_add(&unit->str, "Session: ");

    sprintf(buf, "%u\r\n", unit->info.session);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "\r\n");


    //创建RTP资源
    unit->rtp_resource = RTSPService_RTPUnit_get(unit->service, unit);                              //申请RTP资源节点
    RTPUnit *rtpunit = unit->rtp_resource->dataptr;                                                 //获取RTP资源
    //创建RTP用户
    RTPUser *rtpuser;
    unit->rtp_user = ABMemoryPool_block_malloc(&unit->service->list_node_memory);                   //申请链表节点内存
    rtpuser = ABMemoryPool_block_malloc(&unit->service->rtpuser_memory);                            //申请用户资源
    TWListNode_init(unit->rtp_user, rtpuser);                                                       //将用户添加到节点

    RTPUser_udp_init(rtpuser, "0.0.0.0", unit->info.srtp_port, unit->info.srtcp_port);        //绑定UDP端口

    //配置用户信息
    rtpuser->c_rtp_in.sin_family = AF_INET;
    rtpuser->c_rtp_in.sin_addr.s_addr = unit->c_in.sin_addr.s_addr;                                 //用户IP
    rtpuser->c_rtp_in.sin_port = htons(unit->info.crtp_port);                                       //用户RTP接收端口

    //添加到资源列表
    RTPUnit_client_add(rtpunit, unit->rtp_user);                                                    //添加RTP用户

    return ret;
}

//响应暂停
int rtsp_response_pause(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    char buf[32];
    PBufStr_reset(&unit->str);
    PBufStr_str_add(&unit->str, "RTSP/1.0 200 OK\r\n");
    PBufStr_str_add(&unit->str, "CSeq: ");
    sprintf(buf, "%d\r\n", unit->info.CSeq);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "Server: sunshine/1.11\r\n");
    PBufStr_str_add(&unit->str, "Date: Fri, 22 Jul 2011 07:06:14 GMT\r\n");
    PBufStr_str_add(&unit->str, "Session: ");

    sprintf(buf, "%u\r\n", unit->info.session);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "\r\n");

    return ret;
}

//响应取消
int rtsp_response_teardown(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    char buf[32];
    PBufStr_reset(&unit->str);
    PBufStr_str_add(&unit->str, "RTSP/1.0 200 OK\r\n");
    PBufStr_str_add(&unit->str, "CSeq: ");
    sprintf(buf, "%d\r\n", unit->info.CSeq);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "Server: sunshine/1.11\r\n");
    PBufStr_str_add(&unit->str, "Date: Fri, 22 Jul 2011 07:06:14 GMT\r\n");
    PBufStr_str_add(&unit->str, "Session: ");

    sprintf(buf, "%u\r\n", unit->info.session);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "\r\n");
    return ret;
}

//销毁
int rtsp_response_destory(RTSPUnit *unit) {
    int ret = 0;
    if (unit->rtp_resource == 0)
        return RTSPUNIT_RET_SUCCEED;
    RTPUnit *rtpunit = unit->rtp_resource->dataptr;
    RTPUser_udp_free(unit->rtp_user->dataptr);                                                         //释放套接字
    RTSPService_PortMap_free(unit->service, unit->info.srtp_port);                                      //释放端口
    RTPUnit_client_delete(rtpunit, unit->rtp_user);                                                    //删除RTP用户
    RTSPService_RTPUnit_delete(unit->service, unit->rtp_resource);                                      //释放RTP资源

    ABMemoryPool_block_free(&unit->service->rtpuser_memory, unit->rtp_user->dataptr);                   //释放用户资源
    ABMemoryPool_block_free(&unit->service->list_node_memory, unit->rtp_user);                          //释放链表节点内存
    //@释放RTSP资源
    ABMemoryPool_block_free(&unit->service->rtsp_memory, unit);
    //@去除RTSP任务
    ret = RTSPUNIT_RET_CANCEL;
    return ret;
}

int rtsp_response_Unsupported_Transport(RTSPUnit *unit) {
    int ret = RTSPUNIT_RET_SUCCEED;
    char buf[32];
    PBufStr_reset(&unit->str);
    PBufStr_str_add(&unit->str, "RTSP/1.0 461 Unsupported Transport\r\n");
    PBufStr_str_add(&unit->str, "CSeq: ");
    sprintf(buf, "%d\r\n", unit->info.CSeq);
    PBufStr_str_add(&unit->str, buf);
    PBufStr_str_add(&unit->str, "Server: sunshine/1.11\r\n");
    PBufStr_str_add(&unit->str, "Date: Fri, 22 Jul 2011 07:06:14 GMT\r\n");
    PBufStr_str_add(&unit->str, "\r\n");

    return ret;
}

